#include "param.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "cJSON.h"
#include "log.h"

g_param_t g_param;

bool mqtt_param_parse(cJSON *root)
{
    memset(&g_param, 0, sizeof(g_param));

    cJSON *json_addr = cJSON_GetObjectItem(root, "addr");
    if(json_addr == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    strcpy(g_param.addr, json_addr->valuestring);

    cJSON *json_port = cJSON_GetObjectItem(root, "port");
    if(json_port == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    g_param.port = json_port->valueint;

    cJSON *json_clientID = cJSON_GetObjectItem(root, "clientID");
    if(json_clientID == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    strcpy(g_param.clientID, json_clientID->valuestring);

    cJSON *json_username = cJSON_GetObjectItem(root, "username");
    if(json_username == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    strcpy(g_param.username, json_username->valuestring);

    cJSON *json_password = cJSON_GetObjectItem(root, "password");
    if(json_password == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    strcpy(g_param.password, json_password->valuestring);

    cJSON *json_keepAliveInterval = cJSON_GetObjectItem(root, "keepAliveInterval");
    if(json_keepAliveInterval == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    g_param.keepAliveInterval = json_keepAliveInterval->valueint;

    cJSON *json_ca = cJSON_GetObjectItem(root, "ca_path");
    if(json_ca == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    if(strlen(json_ca->valuestring) == 0)
    {
        g_param.ca.enable = false;
    }
    else
    {
        g_param.ca.enable = true;
        strcpy(g_param.ca.path, json_ca->valuestring);
    }

    cJSON *json_client_crt = cJSON_GetObjectItem(root, "client_crt_path");
    if(json_client_crt == NULL)
    {
        LOG_ERR("Error before: [%s].", cJSON_GetErrorPtr());
        return false;
    }
    if(strlen(json_client_crt->valuestring) == 0)
    {
        g_param.client_crt.enable = false;
    }
    else
    {
        g_param.client_crt.enable = true;
        strcpy(g_param.client_crt.path, json_client_crt->valuestring);
    }

    cJSON *json_client_key = cJSON_GetObjectItem(root, "client_key_path");
    if(json_client_key == NULL)
    {
        LOG_ERR("Error before: [%s].\n", cJSON_GetErrorPtr());
        return false;
    }
    if(strlen(json_client_key->valuestring) == 0)
    {
        g_param.client_key.enable = false;
    }
    else
    {
        g_param.client_key.enable = true;
        strcpy(g_param.client_key.path, json_client_key->valuestring);
    }
 
    LOG_DEBUG("addr = %s", g_param.addr);
    LOG_DEBUG("port = %d", g_param.port);
    LOG_DEBUG("clientID = %s", g_param.clientID);
    LOG_DEBUG("username = %s", g_param.username);
    LOG_DEBUG("password = %s", g_param.password);
    LOG_DEBUG("keepAliveInterval = %d", g_param.keepAliveInterval);
    LOG_DEBUG("ca enable = %d,%s", g_param.ca.enable, g_param.ca.path);
    LOG_DEBUG("ca client_crt = %d,%s", g_param.client_crt.enable, g_param.client_crt.path);
    LOG_DEBUG("ca client_key = %d,%s", g_param.client_key.enable, g_param.client_key.path);

    return true;
}

void param_init()
{
    int fd, ret;
    off_t fd_len;
    cJSON *root;

    fd = open("config.json", O_RDONLY);
    if(fd == -1)
    {
        LOG_ERR("fail to open configuration file.");
        exit(EXIT_FAILURE);
    }

    // 获取文件大小并申请相应大小空间
    fd_len = lseek(fd, 0, SEEK_END);
    if(fd_len == -1)
    {
        close(fd);
        LOG_ERR("fail to execute lseek.");
        exit(EXIT_FAILURE);
    }
    LOG_DEBUG("config.json size = %d.", fd_len);

    void *json_str = malloc(fd_len + 1);
    if(json_str == NULL)
    {   
        close(fd);
        LOG_ERR("fail to allocate memory.");
        exit(EXIT_FAILURE);
    }
    memset(json_str, 0, fd_len + 1);

    ret = pread(fd, json_str, fd_len, 0);
    if(ret != fd_len)
    {
        close(fd);
        free(json_str);
        LOG_ERR("read length is %d.", ret);
        exit(EXIT_FAILURE);
    }

    root = cJSON_Parse(json_str);
    if(root == NULL)
    {
        close(fd);
        free(json_str);
        LOG_ERR("fail to parse JSON.");
        exit(EXIT_FAILURE);
    }
    close(fd);
    free(json_str);

    // 将JSON中的变量储存为全局变量
    ret = mqtt_param_parse(root);
    if(ret == false)
    {
        cJSON_Delete(root);
        LOG_ERR("missing key parameters.");
        exit(EXIT_FAILURE);
    }

    cJSON_Delete(root);

    LOG_INFO("param init success.");
}
